package com.cynteka.cyfoman.core.collection;

import com.cynteka.cyfoman.core.IValueObject;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: Sergey
 * Date: 29.07.11
 * Time: 13:05
 */
public class DBSingleTableHierarchyAppender implements IRegistryAppender {
    private String tableName;
    private String fieldId = "id";
    private String fieldReference;
    private DataSource dataSource;
    private ISQLGenerator sqlGenerator = new BaseSQLGenerator();
    private LinkType linkType = LinkType.ONE_TO_MANY;

    private String collectionId;
    private String linkId;

    public DBSingleTableHierarchyAppender() {
    }

    public String getCollectionId() {
        return collectionId;
    }

    public void setCollectionId(String collectionId) {
        this.collectionId = collectionId;
    }

    public LinkType getLinkType() {
        return linkType;
    }

    public void setLinkType(LinkType linkType) {
        this.linkType = linkType;
    }

    public String getLinkId() {
        return linkId;
    }

    public void setLinkId(String linkId) {
        this.linkId = linkId;
    }

    public class Collection extends BaseCollection<IValueObject<Integer, String>> implements IDBCollection<IValueObject<Integer, String>> {

        public Collection() {
            super(collectionId);
        }

        @Override
        public java.util.Collection<IValueObject<Integer, String>> getItems(Map<String, Object> params) {
            Object parent = params == null ? null : params.get(Constants.PARENT);
            IValueObject voParent = (IValueObject) parent;

            String sql;
            List<IValueObject<Integer, String>> res;
            if (voParent == null) {
                sql = sqlGenerator.generateSelectByFieldNameIsNull(tableName, fieldReference);
                res = new DBUtil<Integer>().queryForValueObjects(dataSource, sql, fieldId, new Object[]{});
            } else {
                sql = sqlGenerator.generateSelectByFieldName(tableName, fieldReference);
                res = new DBUtil<Integer>().queryForValueObjects(dataSource, sql, fieldId, new Object[]{voParent.getId()});

            }
            return res;
        }

        @Override
        public String getTableName() {
            return tableName;
        }
    }

    public class Link extends BaseLink<IValueObject<Integer, String>, IValueObject<Integer, String>> {

        public Link() {
            super(linkId, collectionId, collectionId, linkType);
        }

        @Override
        public java.util.Collection<IValueObject<Integer, String>> getDestinationItems(IValueObject<Integer, String> valueObject) {
            ICollection<IValueObject<Integer, String>> collection = (ICollection<IValueObject<Integer, String>>) getOwner().getCollection(collectionId);

            Map<String, Object> params = new HashMap<String, Object>();
            params.put(Constants.PARENT, valueObject);
            return collection.getItems(params);
        }

        @Override
        public java.util.Collection<IValueObject<Integer, String>> getSourceItems(IValueObject<Integer, String> valueObject) {
            String sql = sqlGenerator.generateSelectByChildId(tableName, fieldId, fieldReference);
            List<IValueObject<Integer, String>> res = new DBUtil<Integer>().queryForValueObjects(dataSource, sql, fieldId, new Object[]{valueObject.getId()});
            return res;
        }
    }

    @Override
    public ICollection[] getCollections() {
        return new ICollection[]{new Collection()};
    }

    @Override
    public ILink[] getLinks() {
        return new ILink[]{new Link()};
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getFieldId() {
        return fieldId;
    }

    public void setFieldId(String fieldId) {
        this.fieldId = fieldId;
    }

    public String getFieldReference() {
        return fieldReference;
    }

    public void setFieldReference(String fieldReference) {
        this.fieldReference = fieldReference;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public ISQLGenerator getSqlGenerator() {
        return sqlGenerator;
    }

    public void setSqlGenerator(ISQLGenerator sqlGenerator) {
        this.sqlGenerator = sqlGenerator;
    }
}
